package com.levi.juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁，用while循环一直判断，直到成功为止 底层使用的是CAS
 *
 * 以下代码使用自旋锁实现自定义锁
 */
class SpinLock {
    public static void main(String[] args) throws InterruptedException {
        MyLock lock = new MyLock();
        new Thread(()->{
            lock.lock();
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
        },"a").start();

        TimeUnit.SECONDS.sleep(2);
        new Thread(()->{
            lock.lock();

            lock.unlock();
        },"b").start();
    }
}



class MyLock{
    //创建一个Thread类型的初始值为null的原子引用
    AtomicReference<Thread> atomicReference = new AtomicReference<>(null);

    /**
     * 加锁
     */
    public void lock() {
        Thread thread = Thread.currentThread();
        //当前线程不为null的话说明已经有线程进来了, 使用自旋锁一直判断，阻塞到这里
        while (!atomicReference.compareAndSet(null, thread)) {

        }
        System.out.println(Thread.currentThread().getName()+"得到锁");
    }

    /**
     * 解锁
     */
    public void unlock() {
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread, null);
        System.out.println(Thread.currentThread().getName()+"释放锁");
    }

}

/*class YourLock{
    AtomicReference atomicReference = new AtomicReference<Thread>();

    //加锁
    public void lock() {
        Thread thread = Thread.currentThread();
        //当前线程不为空说明有线程进来了，就一直阻塞在那里
        while (!atomicReference.compareAndSet(null, thread)) {

        }
        System.out.println(thread.getName()+" 得到了锁");
    }

    //解锁
    public void unlock() {
        Thread thread = Thread.currentThread();
        if (atomicReference.compareAndSet(thread, null)) {
            System.out.println(thread.getName()+" 释放了锁!");
        }
    }
}*/
